<?php

class ActivityAnniversaryService extends AbstractService
{
    const ActivityShare             = 2;  // 分享活动
    const ActivityInvite            = 6;  // 分享邀请好友活动
    const ActivityJump              = 7;  // 中秋跳跃活动
    const ActivitySynthesis         = 8;  // 万圣节合成活动
    const ActivityFirstPay          = 9;  // 首充
    const ActivityLottery           = 10; // 转盘抽奖
    const ActivityChristmas         = 11; // 圣诞树
    const ActivityPay               = 12; // 充值活动
    const ActivityTree              = 13; // 春节树活动
    const ActivityValentine         = 14; // 情人节活动
    const ActivityValentine1        = 15; // 女王节活动
    const ActivityPersonalGoals     = 16; // 个人目标活动
    const ActivityChildren          = 17;  //儿童节活动
    const ActivityAnniversary       = 19;  //周年庆
    const PrivateKey                = 'a4FgAs1d7Sg8Ndfs6c2def5360dd26';

    /**
     * @var ActivityAnniversaryService
     */
    private static $instance;

    /**
     * Get the instance of ActivityAnniversaryService.
     *
     * @return ActivityAnniversaryService
     */
    public static function get()
    {
        if (!self::$instance) {
            self::$instance = new ActivityAnniversaryService();
        }
        return self::$instance;
    }

    /**
     * Construction.
     */
    protected function __construct()
    {
        parent::__construct();
    }

    /**
     * 处理用户创建时的逻辑
     *
     * @param int $shardId
     * @return void
     */
    public function handleCreate($shardId)
    {

    }

    /**
     * 处理用户登录时的逻辑
     *
     * @param int $userId
     * @return void
     */
    public function handleLogin($userId)
    {
        // do nothing
    }

    /**
     * 处理 service 对外提供的全量数据
     *
     * @param int $userId
     * @return array
     */
    public function info($userId)
    {
        return $this->getAnniversaryInfo();
    }

    /**
     * 获取周年庆数据
     * @param $userId
     * @param $activityId
     * @param $reqTime
     * @return array
     * @throws SzException
     */
    public function getAnniversaryInfo($userId, $activityId, $reqTime)
    {
        //获取活动配置
        $activityConf = SzConfig::get()->loadAppConfig(GameConst::CONFIG_GAME_EVENT, $activityId, true);
        $this->checkAnniversaryOpen($activityConf,$reqTime);
        $openDays = ceil(($activityConf['endTime'] - $activityConf['startTime'])/86400);

        $firstConf = SzConfig::get()->loadAppConfig(GameConst::CONFIG_GAME_ACTIVITY_ANNIVERSARY, 1, true);
        //获取当天过期时间戳
        $firstDay = strtotime(date('Y-m-d',$firstConf['startTime']));
        $overCheckDays = ceil(($reqTime - $firstDay)/86400);
        $overActivityDays = ceil(($reqTime - $activityConf['startTime'])/86400);

        /**
         * @var AnniversaryInfoVoList $activityAnniversaryList
         * @var AnniversaryInfoVo $activityAnniversary
         */
        //获取玩家活动数据模块
        $activityAnniversaryList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_ACTIVITY_ANNIVERSARY_INFO);
        $activityAnniversaryDatas = $activityAnniversaryList->toArray();
        $checkRecordStr = '';
        $overRecordStr = '';

        $isCreate = true;
        $anniversaryArr = array();
        foreach ($activityAnniversaryDatas as $aid=>$data){
            if ($activityId == $aid){
                $isCreate = false;
                $anniversaryArr = $data;
                break;
            }
        }

        $activityAnniversary = $activityAnniversaryList->getElement($activityId,false);
        /**
         * @var ModuleProfileInfoVoList $profileInfoList
         * @var ModuleProfileInfoVo $profileInfoFlower
         * @var ModuleProfileInfoVo $profileInfoSeed
         * @var ModuleProfileInfoVo $profileInfoTable
         * @var ModuleProfileInfoVo $flower
         * @var ModuleProfileInfoVo $seed
         * @var ModuleProfileInfoVo $table
         */
        $profileInfoList = SzPersister::get()->getVoList($userId, ModuleProfileConst::ORM_NAME_PROFILE_INFO);

        //玩家周年庆buff
        $profileInfoFlower = $profileInfoList->getElement(GameConst::USER_ANNIVERSARY_GET_FLOWER, false);
        $profileInfoSeed = $profileInfoList->getElement(GameConst::USER_ANNIVERSARY_GET_SEED, false);
        $profileInfoTable = $profileInfoList->getElement(GameConst::USER_ANNIVERSARY_SHOP_TABLE, false);
        if ($isCreate){
            if (!$activityAnniversary){
                //制作过期数据
                if ($overCheckDays != 1){//玩家在周年庆期间登陆
                    for ($j=1 ; $j<=$openDays ; $j++){
                        if ($j == 1){
                            $checkRecordStr = '0';
                            $overRecordStr = '1';
                        }
                        else{
                            if ($j < $overCheckDays){
                                $overRecordStr = $overRecordStr.',1';
                            }
                            else{
                                $overRecordStr = $overRecordStr.',0';
                            }
                            $checkRecordStr = $checkRecordStr.',0';
                        }
                    }
                }
                else{//玩家在周年庆开启时登陆
                    //制作签到初始化
                    for ($i=1 ; $i<=$openDays ; $i++){
                        if ($i == 1){
                            $checkRecordStr = '0';
                            $overRecordStr = '0';
                        }
                        else{
                            $checkRecordStr = $checkRecordStr.',0';
                            $overRecordStr = $overRecordStr.',0';
                        }
                    }
                }

                $activityAnniversary = new AnniversaryInfoVo(
                    $userId, // userId
                    $activityId, //$activityId
                    1,
                    0,
                    json_encode($checkRecordStr),
                    json_encode($overRecordStr),
                    json_encode(''),
                    0,
                    $reqTime,
                    $reqTime,
                    $activityConf['endTime'],
                    true
                );

                if ($activityAnniversary->isInsert() && !SzUtility::checkArrayKey($activityId, $activityAnniversaryList->getList())) {
                    $activityAnniversaryList->addElement($activityAnniversary);
                    $activityAnniversaryList->setElement($activityId,$activityAnniversary);
                }
                $anniversaryArr = $activityAnniversary->toArray();
            }

            if (!$profileInfoFlower) {
                $profileInfoFlower = new ModuleProfileInfoVo(
                    $userId,
                    GameConst::USER_ANNIVERSARY_GET_FLOWER,
                    $activityConf['endTime'],
                    $reqTime,
                    true
                );
                $profileInfoList->addElement($profileInfoFlower);
                $profileInfoList->setElement(GameConst::USER_ANNIVERSARY_GET_FLOWER, $profileInfoFlower);
            }
            else{
                $profileInfoFlower->setInfo($activityConf['endTime']);
                $profileInfoList->updateElement(GameConst::USER_ANNIVERSARY_GET_FLOWER, $profileInfoFlower);
            }

            if (!$profileInfoSeed) {
                $profileInfoSeed = new ModuleProfileInfoVo(
                    $userId,
                    GameConst::USER_ANNIVERSARY_GET_SEED,
                    $activityConf['endTime'],
                    $reqTime,
                    true
                );
                $profileInfoList->addElement($profileInfoSeed);
                $profileInfoList->setElement(GameConst::USER_ANNIVERSARY_GET_SEED, $profileInfoSeed);
            }
            else{
                $profileInfoSeed->setInfo($activityConf['endTime']);
                $profileInfoList->updateElement(GameConst::USER_ANNIVERSARY_GET_SEED, $profileInfoSeed);
            }

            if (!$profileInfoTable) {
                $profileInfoTable = new ModuleProfileInfoVo(
                    $userId,
                    GameConst::USER_ANNIVERSARY_SHOP_TABLE,
                    $activityConf['endTime'],
                    $reqTime,
                    true
                );
                $profileInfoList->addElement($profileInfoTable);
                $profileInfoList->setElement(GameConst::USER_ANNIVERSARY_SHOP_TABLE, $profileInfoTable);
            }
            else{
                $profileInfoTable->setInfo($activityConf['endTime']);
                $profileInfoList->updateElement(GameConst::USER_ANNIVERSARY_SHOP_TABLE, $profileInfoTable);
            }
        }
        else{
            //获取最新签到时间
            $checkTime = $activityAnniversary->getCheckTime();
            //获取当天过期时间戳
            $today = strtotime(date('Y-m-d',$reqTime));
            if ($checkTime < $today && $overCheckDays != 1){
                //更新签到过期状态
                $check = explode(',',json_decode($activityAnniversary->getCheckRecord()));
                $over = explode(',',json_decode($activityAnniversary->getOverRecord()));
                for ($j=1 ; $j<$overCheckDays ; $j++){
                    if ($over[$j - 1] == 0 && $check[$j - 1] == 0){
                        $over[$j - 1] = 1;
                    }
                    if ($check[$j - 1] == 1){
                        $over[$j - 1] = 0;
                    }
                }
                $checkRecordStr = implode(',',$check);
                $overRecordStr = implode(',',$over);
                $activityAnniversary->setCheckRecord($checkRecordStr);
                $activityAnniversary->setOverRecord($overRecordStr);

                $activityAnniversaryList->updateElement($activityId,$activityAnniversary);
            }
        }

        SzPersister::get()->setVoList($activityAnniversaryList);
        SzPersister::get()->setVoList($profileInfoList);

        //获取玩家阶段购买数据20200703
//        $stepBuyInfo = $this->getStepAnniversary($userId, $activityId, $reqTime);

        if (!$isCreate){
            $anniversaryArr = $activityAnniversary->toArray();
            $checkRecordStr = $anniversaryArr['checkRecord'];
            $overRecordStr = $anniversaryArr['overRecord'];
        }

        //进行数据处理
        $checkAndOver = $this->makeCheckOrOver($checkRecordStr,$overRecordStr,$openDays);
        unset($anniversaryArr['checkRecord']);
        unset($anniversaryArr['overRecord']);
        $anniversaryArr['punch'] = empty($checkAndOver) ? array() : $checkAndOver;


        $flowerTime = $activityConf['endTime'];
        $seedTime = $activityConf['endTime'];
        $tableTime = $activityConf['endTime'];
        return array(
            'anniversary' => $anniversaryArr,
            'stepBuyInfo' => array(),//$stepBuyInfo,
            'buffInfo' => array(
                GameConst::USER_ANNIVERSARY_GET_FLOWER => $flowerTime,
                GameConst::USER_ANNIVERSARY_GET_SEED => $seedTime,
                GameConst::USER_ANNIVERSARY_SHOP_TABLE => $tableTime
            )
        );
    }

    //检测活动开启
    public function checkAnniversaryOpen($activityConf,$reqTime){
        $serverTime = $reqTime == 0 ? GameService::get()->getReqTime() : $reqTime;
        $startTime = $activityConf['startTime'];
        if ($startTime > $serverTime) {
            throw new SzException(90001);//活动没开
        }
        $endTime = $activityConf['endTime'];
        if ($endTime < $serverTime) {
            throw new SzException(90002);//活动结束
        }
        if ($activityConf['type'] != self::ActivityAnniversary) {
            throw new SzException(90101);//不是周年庆活动
        }
    }

    //获取玩家阶段购买数据
    public function getStepAnniversary($userId,$activityId,$reqTime){
        //获取活动配置
        $activityConf = SzConfig::get()->loadAppConfig(GameConst::CONFIG_GAME_EVENT, $activityId, true);
        /**
         * @var AnniversaryStepVoList $anniversaryStepList
         * @var AnniversaryStepVo $anniversaryStep
         */
        //获取玩家活动数据模块
        $anniversaryStepList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_ACTIVITY_ANNIVERSARY_STEP);
        $anniversaryStepDatas = $anniversaryStepList->toArray();

        $isCreate = false;
        $stepArr = array();
        foreach ($anniversaryStepDatas as $aid=>$data){
            if ($activityId == $data['aId']){
                $isCreate = true;
                $stepArr = $data;
                break;
            }
        }

        $anniversaryStep = $anniversaryStepList->getElement($activityId,false);
        if (!$isCreate){
            if (!$anniversaryStep){
                $anniversaryStep = new AnniversaryStepVo(
                    $userId, // userId
                    $activityId, //$activityId
                    1,
                    (string)'',
                    $reqTime,
                    $reqTime,
                    $activityConf['endTime'],
                    true
                );
            }

            if ($anniversaryStep->isInsert() && !SzUtility::checkArrayKey($activityId, $anniversaryStepList->getList())) {
                $anniversaryStepList->addElement($anniversaryStep);
                $anniversaryStepList->setElement($activityId,$anniversaryStep);
            }
            $stepArr = $anniversaryStep->toArray();
        }

        SzPersister::get()->setVoList($anniversaryStepList);

        return $stepArr;
    }

    //制作签到Or过期数据
    public function makeCheckOrOver($checkRecordStr,$overRecordStr,$openDays){
        $checkOrOver = array();
        for ($i = 1 ; $i <= $openDays ; $i++){
            $checkOrOver[$i] = 0;
        }

        //签到过期数据组合
        $checkArr= explode(',',$checkRecordStr);
        foreach ($checkArr as $day1=>$state1){
            if ($state1 == 1){
                $checkOrOver[$day1 + 1] = 1;
            }
            else{
                $checkOrOver[$day1 + 1] = 0;
            }
        }

        $overArr= explode(',',$overRecordStr);
        foreach ($overArr as $day2=>$state2){
            if ($checkOrOver[$day2 + 1] == 1){
                continue;
            }
            if ($state2 == 1){
                $checkOrOver[$day2 + 1] = 2;
            }
            else{
                $checkOrOver[$day2 + 1] = 0;
            }
        }

        return $checkOrOver;
    }

    /**
     * 打卡签到
     * @param $userId
     * @param $activityId
     * @param $day
     * @param $reqTime
     * @return bool
     * @throws SzException
     */
    public function checkInByCard($userId, $activityId, $day,$reqTime)
    {
        //获取活动配置
        $activityConf = SzConfig::get()->loadAppConfig(GameConst::CONFIG_GAME_EVENT, $activityId, true);
        $this->checkAnniversaryOpen($activityConf,$reqTime);
        $firstConf = SzConfig::get()->loadAppConfig(GameConst::CONFIG_GAME_ACTIVITY_ANNIVERSARY, 1, true);
        $openDays = ceil(($activityConf['endTime'] - $activityConf['startTime'])/86400);
        //获取当天过期时间戳
        $firstDay = strtotime(date('Y-m-d',$firstConf['startTime']));
        $overDays = ceil(($reqTime - $firstDay)/86400);
        if ($openDays < $day){
            throw new SzException(90102);//签到天数不在活动范围内
        }
        if ($overDays != $day){
            throw new SzException(90103);//签到天数错误
        }
        $rewardConf = SzConfig::get()->loadAppConfig(GameConst::CONFIG_GAME_ACTIVITY_ANNIVERSARY, $overDays, true);
        if ($reqTime < $rewardConf['startTime'] || $reqTime > $rewardConf['endTime']){
            throw new SzException(90104);//不是当天领奖配置
        }

        /**
         * @var AnniversaryInfoVoList $activityAnniversaryList
         * @var AnniversaryInfoVo $activityAnniversary
         */
        //获取玩家活动数据模块
        $activityAnniversaryList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_ACTIVITY_ANNIVERSARY_INFO);
        $activityAnniversary = $activityAnniversaryList->getElement($activityId,false);
        if (!$activityAnniversary){
            throw new SzException(90105);//活动没有数据
        }

        //验证玩家是否可以签到
        $check = explode(',',json_decode($activityAnniversary->getCheckRecord()));
        if ($check[$overDays-1] == 1){
            throw new SzException(90106);//已签到
        }
        $over = explode(',',json_decode($activityAnniversary->getOverRecord()));
        if ($over[$overDays-1] == 1){
            throw new SzException(90107);//已过期
        }

        //更新数据
        $check[$overDays - 1] = 1;
        $over[$overDays - 1] = 0;
        $activityAnniversary->setCheckRecord(implode(',',$check));
        $activityAnniversary->setOverRecord(implode(',',$over));
        $activityAnniversary->setCheckTime($reqTime);
        $activityAnniversaryList->updateElement($activityId,$activityAnniversary);
        SzPersister::get()->setVoList($activityAnniversaryList);
        //发放道具
        foreach ($rewardConf['rewardId'] as $item=>$num){
            GameService::get()->handleEntity($userId, $item, $num, true, true);
        }

        return true;
    }

    /**
     * 购买特惠
     * @param $userId
     * @param $activityId
     * @param $reqTime
     * @return array
     * @throws SzException
     */
    public function buyPreferential($userId, $activityId, $reqTime)
    {
        //获取活动配置
        $activityConf = SzConfig::get()->loadAppConfig(GameConst::CONFIG_GAME_EVENT, $activityId, true);
        $this->checkAnniversaryOpen($activityConf,$reqTime);

        /**
         * @var AnniversaryInfoVoList $activityAnniversaryList
         * @var AnniversaryInfoVo $activityAnniversary
         */
        //获取玩家活动数据模块
        $activityAnniversaryList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_ACTIVITY_ANNIVERSARY_INFO);
        $activityAnniversary = $activityAnniversaryList->getElement($activityId,false);
        if (!$activityAnniversary){
//            throw new SzException(90001);//活动未开启
            return array(
                'code' => -1,
                'cdTime' => 0
            );
        }

        $hasPreferential =  $activityAnniversary->getPreferential();
        if ($hasPreferential != 1){
//            throw new SzException(90001);//无特惠礼包可购买
            return array(
                'code' => -1,
                'cdTime' => 0
            );
        }

        $cdTime = $activityAnniversary->getCdTime();
        if ($reqTime < $cdTime){
//            throw new SzException(90001);//特惠礼包冷却
            return array(
                'code' => -1,
                'cdTime' => 0
            );
        }

        //获取相关配置
        $buyConfig = SzConfig::get()->loadAppConfig(ModuleProfileConst::CONFIG_PROFILE, 'anniversaryGiftBuy', true);
        //消耗钻石
        GameService::get()->handleEntity($userId, GameConst::ENTITY_ACTION_CONSUME_MONEY, $buyConfig['value'], true, true);

        $cdConfig = SzConfig::get()->loadAppConfig(ModuleProfileConst::CONFIG_PROFILE, 'anniversaryGiftCD', true);
        $activityAnniversary->setCdTime($reqTime + json_decode($cdConfig['value'])[0]);
        $activityAnniversaryList->updateElement($activityId,$activityAnniversary);
        SzPersister::get()->setVoList($activityAnniversaryList);

        //发放道具
        $getConfig = json_decode(SzConfig::get()->loadAppConfig(ModuleProfileConst::CONFIG_PROFILE, 'anniversaryGiftID', true)['value']);
        foreach ($getConfig as $item=>$num){
            GameService::get()->handleEntity($userId, $item, $num, true, true);
        }

        return array(
            'code' => 0,
            'cdTime' => $reqTime + json_decode($cdConfig['value'])[0]
        );
    }

    /**
     * 清理特惠时间
     * @param $userId
     * @param $activityId
     * @param $reqTime
     * @return bool
     * @throws SzException
     */
    public function buyPreferentialCdTime($userId, $activityId, $reqTime)
    {
        //获取活动配置
        $activityConf = SzConfig::get()->loadAppConfig(GameConst::CONFIG_GAME_EVENT, $activityId, true);
        $this->checkAnniversaryOpen($activityConf,$reqTime);
        /**
         * @var AnniversaryInfoVoList $activityAnniversaryList
         * @var AnniversaryInfoVo $activityAnniversary
         */
        //获取玩家活动数据模块
        $activityAnniversaryList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_ACTIVITY_ANNIVERSARY_INFO);
        $activityAnniversary = $activityAnniversaryList->getElement($activityId,false);
        if (!$activityAnniversary){
            throw new SzException(90105);//活动没有数据
        }

        $hasPreferential =  $activityAnniversary->getPreferential();
        if ($hasPreferential != 1){
            throw new SzException(90108);//无特惠礼包可购买
        }
        $cdTime = $activityAnniversary->getCdTime();
        if ($reqTime > $cdTime + 1 && $cdTime != 0){
            throw new SzException(90109);//无需清理冷却时间
        }

        //获取相关配置
        $config = json_decode(SzConfig::get()->loadAppConfig(ModuleProfileConst::CONFIG_PROFILE, 'anniversaryGiftCD', true)['value']);
        //消耗钻石
        GameService::get()->handleEntity($userId, GameConst::ENTITY_ACTION_CONSUME_MONEY, $config[1], true, true);
        $activityAnniversary->setCdTime(0);
        $activityAnniversaryList->updateElement($activityId,$activityAnniversary);
        SzPersister::get()->setVoList($activityAnniversaryList);

        return true;
    }

    /**
     * 获取活动id
     * @param $userId int
     * @return int
     */
    public function getAnniversaryIndexId($userId) {
        $serverTime = GameService::get()->getReqTime();
        $activityList = SzConfig::get()->loadAppConfig(GameConst::CONFIG_GAME_EVENT, null, true);
        if (!$activityList) {
            return 0;
        }

        $userLevel = UserService::get()->getUserLevel($userId);

        foreach ($activityList as $activity) {
            $startTime = $activity['startTime'];
            $endTime = $activity['endTime'];
            $type = $activity['type'];
            if ($type == self::ActivityAnniversary && $serverTime >= $startTime && $serverTime <= $endTime && $userLevel >= $activity['triggerLv']) {
                return $activity['indexId'];
            }
        }

        return 0;
    }
}